package server;
// This file contains material supporting section 3.7 of the textbook:
// "Object Oriented Software Engineering" and is issued under the open-source
// license found at www.lloseng.com 

import java.io.*;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import control.AbstractControl;
import daemon.Daemon;
import ocsf.server.*;


/**
 * This class overrides some of the methods in the abstract 
 * superclass in order to give more functionality to the server.
 *
 */
public class EchoServer extends AbstractServer 
{
  //Class variables *************************************************
  
  /**
   * The default port to listen on.
   */
  final public static int DEFAULT_PORT = 5555;
  
  public static Connection connectionToDB;//With this var you can access into the DB
  
  static public HashMap<Integer,Queue<Integer>> bookOrdersQueue;
  static public Boolean ServerAlive=false;
  static public ArrayList<String> connectedclients;
  
  
  //Constructors ****************************************************
  
  /**
   * Constructs an instance of the echo server.
   *
   * @param port The port number to connect on.
   */
  public EchoServer(int port) 
  {
    super(port);
  }
  public EchoServer(int port,String address,String user,String pass,String dbname) throws SQLException 
  {
    super(port);
    ServerAlive=true;
    connectionToDB=mysqlConnection.openConnection(address,user,pass,dbname);
    connectedclients = new ArrayList<String>();
    initGlobalHashMap();//need to init the bookOrdersQueue
    Daemon serverDaemon=new Daemon();
    (new Thread(serverDaemon)).start();
  }
  
  //Instance methods ************************************************
  
  /**
   * This method handles any messages received from the client.
   *
   * @param msg The message received from the client.
   * @param client The connection from which the message originated.
   */
  public void handleMessageFromClient
    (Object msg, ConnectionToClient client)
  {
	  String[] temp=(String[])msg;
	  if (!temp[0].contentEquals("quit"))
	  {
		Object r=AbstractControl.initialize((String[])msg,client);
	    System.out.println("Message received: " + ((String[])msg)[0] + " from " + client);
	   // String r =mysqlConnection.openconnection((String) msg);
	    try {
			client.sendToClient(r);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    //  this.sendToAllClients(msg);
	  } else
		try {
	  		ServerGUI.listModel.removeElement((client.getInetAddress().toString()));
			client.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
  }
    
  /**
   * This method overrides the one in the superclass.  Called
   * when the server starts listening for connections.
   */
  protected void serverStarted()
  {
    System.out.println
      ("Server listening for connections on port " + getPort());
  }
  
  /**
   * This method overrides the one in the superclass.  Called
   * when the server stops listening for connections.
   */
  protected void serverStopped()
  {
    System.out.println
      ("Server has stopped listening for connections.");
  }
  

  /**
 * Initiate our GlobalHashMap that contains the logic of orders books
 */
protected void initGlobalHashMap()
  {
	  String[][] result= mysqlConnection.select("select bid,amount from test.booktitle;",2);
	  String[][] ordersresult=mysqlConnection.select("select bid,sid from test.orders order by bid,indexinqueue;",2);
	  bookOrdersQueue=new HashMap<Integer,Queue<Integer>>();  
	  for(int i=0;i<result.length;i++)
	  {
		  	  Queue<Integer> q=new ArrayBlockingQueue<Integer>(Integer.parseInt(result[i][1])); // amount
			  Integer id=new Integer(Integer.parseInt(result[i][0]));  // bid 
			  bookOrdersQueue.put(id,q);
	  }
	  for (int i=0;i<ordersresult.length;i++)
	  {
		  bookOrdersQueue.get(Integer.parseInt(ordersresult[i][0])).add(Integer.parseInt(ordersresult[i][1]));
	  }
  }
  synchronized protected void clientDisconnected(
		    ConnectionToClient client) {
	  		connectedclients.remove(client.getName());

  }
  protected void clientConnected(ConnectionToClient client) {
	  client.setName("User" + new Random().nextInt()%10000);
	  ServerGUI.listModel.addElement(client.getInetAddress().toString());
  }




	public static void sendEmailNotification(String emailAddress, String theEmailText)
	{
		final String username = "ortbraudelibrary@gmail.com";
		final String password = "malshin123";
	
		Properties props = new Properties();
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.starttls.enable", "true");
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.smtp.port", "587");
	
		Session session = Session.getInstance(props,
		  new javax.mail.Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(username, password);
			}
		  });
	
		try {
	
			Message message = new MimeMessage(session);
			message.setFrom(new InternetAddress("menashes87@gmail.com"));
			message.setRecipients(Message.RecipientType.TO,
				InternetAddress.parse(emailAddress));
			message.setSubject("OBL Notification");
			message.setText(theEmailText);
	
			Transport.send(message);
	
			System.out.println("Done");
	
		} catch (MessagingException e) {
			
		}
		
	}
}//End of EchoServer class